/**
 * 
 * 
 * @author Antonio Sorgente 
 * @version 1.0
 * @since 2012
 * @comment package per manipolare i file properties
 * 
 */
package configurationproperties;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
import java.util.Properties;

import configurationproperties.exceptions.MissingPropertyException;
import configurationproperties.exceptions.PropertiesFileNotLoadException;

public class ConfigurationProperties {

	private String filePropertiesName = "";
	private Properties properties = null;

	public ConfigurationProperties() throws FileNotFoundException {
		this("config.properties");

	}

	/**
	 * Carica il file properties tra i sorgenti del package/jar
	 * 
	 * @param c
	 * @param path
	 */
	public ConfigurationProperties(Class c, String path) {
		this(c, path, null);
	}

	public ConfigurationProperties(Class c, String baseName,
			Locale currentLocale) {
		String localName;
		if (currentLocale == null) {
			localName = baseName;
		} else {
			localName = this
					.getLocalNameFileProperties(baseName, currentLocale);
		}

		this.filePropertiesName = localName;
		InputStream is = c.getClass().getResourceAsStream(localName);

		try {
			properties = new Properties();
			properties.load(is);
		} catch (IOException e) {
			properties = null;
			e.printStackTrace();
		}

	}

	public ConfigurationProperties(String baseName) throws FileNotFoundException {
		this(baseName, null);
	}

	public ConfigurationProperties(String baseName, Locale currentLocale) throws FileNotFoundException {
		String localName;
		if (currentLocale == null) {
			localName = baseName;
		} else {
			localName = this
					.getLocalNameFileProperties(baseName, currentLocale);
		}

		this.filePropertiesName = localName;
		try {
			
			properties = new Properties();
			properties.load(new FileInputStream(localName));
		} catch (FileNotFoundException e) {
			throw new FileNotFoundException("Errore durante la fase di lettura del file: " + baseName +", file inesistente" +
						"\nErrore: " + e.getMessage());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			properties = null;
			e.printStackTrace();
		}
	}

	private String getLocalNameFileProperties(String baseName,
			Locale currentLocale) {
		String localName = baseName.replaceAll(
				"\\.properties",
				"_" + currentLocale.getLanguage() + "_"
						+ currentLocale.getCountry() + "\\.properties");

		return localName;

	}

	// private ConfigurationProperties(Properties props) {
	// this.filePropertiesName = "";
	// this.props = props;
	// }

	/**
	 * 
	 * QUESTO METODO PERMETTE DI RECUPERARE UN VALORE DAL FILE CONFIG.PROPERTIES
	 * 
	 * @param pKey
	 *            DI TIPO STRING
	 * @return VALORE DI KEY SE PRESENTE - ALTRIMENTI STRINGA VUOTA
	 * @throws MissingPropertyException
	 * @throws PropertiesFileNotLoadException
	 * 
	 */
	public synchronized String getString(String pKey)
			throws MissingPropertyException, PropertiesFileNotLoadException {

		String returnValue = "";

		if (properties == null) {
			throw new PropertiesFileNotLoadException();
		}

		returnValue = properties.getProperty(pKey);

		if (returnValue == null) {
			throw new MissingPropertyException();
		} else {
			return returnValue;
		}
	}

	/**
	 * QUESTO METODO PERMETTE DI SCRIVERE UN VALORE NEL FILE CONFIG.PROPERTIES
	 * 
	 * 
	 * @param pKey
	 *            DI TIPO STRING - RAPPRESENTA LA CHIAVE DA INSERIRE
	 * @param pValue
	 *            DI TIPO STRING - RAPPRESENTA IL VALORE CHE SI VUOLE ATTRIBUIRE
	 *            ALLA CHIAVE
	 * @throws PropertiesFileNotLoadException
	 * 
	 * 
	 */
	public synchronized void setProperty(String pKey, String pValue)
			throws PropertiesFileNotLoadException {

		if (properties == null) {
			throw new PropertiesFileNotLoadException();
		}
		properties.setProperty(pKey, pValue);

	}

	
	public synchronized void saveProperty() throws IOException {
		this.saveProperty(filePropertiesName);		
	}

	public synchronized void saveProperty(String path) throws IOException {
		try {

			properties.store(new FileOutputStream(path), null);
		} catch (IOException e) {
			throw new IOException("Errore nel salvataggio del file: "
					+ filePropertiesName + "\nErrore: " + e.getMessage());
		}

	}

	
	public synchronized Properties getProperties(){
		return this.properties;
		
	}
}
